# -*- coding:utf-8 -*-
from datetime import datetime, timedelta

from flask import render_template, request, current_app, session, redirect, url_for, g, abort

from info import db
from . import admin_blu
from ... import constants
from ...libs.qiniuyun.image_storage import storage
from ...models import User, LoginInfoCount, News, Category, LoginInfo
from ...utils.common import get_user_info, get_category_info
from ...utils.resonse import info_jsonfy
from ...utils.response_code import RET
from ...utils.utils import random_uuid


@admin_blu.route("/createSuperUser", methods=["GET"])
@get_user_info
def create_super_user():
    data = {}
    # 先去数据库查超级管理员账户信息
    try:
        userModels = User.query.filter(User.is_admin == True)
    except Exception as e:
        data["msg"] = "数据库查询失败"
        current_app.logger.error(e)
    else:
        flag = False
        superUserIdList = [u.id for u in userModels]
        if superUserIdList:
            user = g.user
            if user:
                currentUserId = user.id
                if currentUserId in superUserIdList:
                    flag = True
                else:
                    return info_jsonfy(500, "当前用户暂无权限，请使用管理员账户来创建")
            else:
                return info_jsonfy(500, "请使用管理员账户来创建")

        dataDict = request.args
        userName = dataDict.get("userName")
        password = dataDict.get("password")
        if not all([userName, password]):
            current_app.logger.error("超级管理员用户名和密码不能为空")
            return info_jsonfy(500, "超级管理员用户名和密码不能为空")
        if flag and (userName in [u.nick_name for u in userModels]):
            return info_jsonfy(500, "该账户已存在")
        user = User()
        user.id = random_uuid()
        user.nick_name = user.mobile = userName
        user.password = password
        user.is_admin = True

        try:
            db.session.add(user)
        except Exception as e:
            current_app.logger.error(e)
            return info_jsonfy(500, f"添加管理员账户失败，请稍后重试")
        else:
            db.session.commit()

        data = {
            "userName": userName,
            "password": password
        }
        current_app.logger.info(f"添加管理员账户成功，userName={userName}，password={password}")
        return info_jsonfy(200, f"添加管理员账户成功", data)


@admin_blu.route("/login", methods=["GET", "POST"])
def login():
    """管理员登录"""
    data = {}
    if request.method == "GET":
        isAdmin = session.get("isAdmin")
        if isAdmin:
            return redirect(url_for("admin.index"))
        return render_template("admin/login.html", data=data)
    else:
        # 校验参数
        data_dict = request.form
        name = data_dict.get("username")
        password = data_dict.get("password")

        if not all([name, password]):
            data["msg"] = "参数有误"

        user = None
        try:
            user = User.query.filter(User.mobile == name, User.is_admin == True).first()
        except Exception as e:
            data["msg"] = "数据库查询失败"
            current_app.logger.error(e)

        if not user:
            data["msg"] = "该用户不是管理员"
        elif not user.check_password(password):
            data["msg"] = "用户名或密码错误"

        if data.get("msg"):
            return render_template("admin/login.html", data=data)

        user.last_login = datetime.now()

        # 保存session信息
        session["userId"] = user.id
        session["mobile"] = user.mobile
        session["nickName"] = user.nick_name
        session["isAdmin"] = True

        return redirect(url_for("admin.index"))


@admin_blu.route("/index")
@get_user_info
def index():
    """管理员首页"""
    user = g.user
    data = {
        "user": user.to_admin_dict()
    }
    return render_template("admin/index.html", data=data)


@admin_blu.route("user_count")
def user_count():
    """用户数量统计"""
    # 获取当前日期
    nowDateStr = datetime.now().strftime("%Y-%m-%d")
    nowMonth = datetime.strptime(nowDateStr[:-2] + "01", "%Y-%m-%d")
    nowDay = datetime.strptime(nowDateStr, "%Y-%m-%d")

    # 总用户数量
    totalUserCount = 0
    try:
        totalUserCount = User.query.filter(User.is_admin == False).count()
    except Exception as e:
        current_app.logger.error(e)

    # 本月新增用户
    nowMonthNewUserCount = 0
    try:
        nowMonthNewUserCount = User.query.filter(User.create_time >= nowMonth, User.is_admin == False).count()
    except Exception as e:
        current_app.logger.error(e)

    # 当日新增用户
    nowDayNewUserCount = 0
    try:
        nowDayNewUserCount = User.query.filter(User.create_time >= nowDay, User.is_admin == False).count()
    except Exception as e:
        current_app.logger.error(e)

    # 当日活跃用户
    nowDayStart = datetime.strptime(nowDateStr + " 00:00:00", "%Y-%m-%d %H:%M:%S")
    nowDayEnd = datetime.strptime(nowDateStr + " 23:59:59", "%Y-%m-%d %H:%M:%S")
    nowDayActiveUserCount = 0
    try:
        nowDayActiveUserCount = LoginInfo.query.filter(LoginInfo.login_time >= nowDayStart,
                                                       LoginInfo.login_time <= nowDayEnd).count()
    except Exception as e:
        current_app.logger.error(e)

    # 30天内每天活跃用户数
    thirtyAgoDate = nowDay - timedelta(seconds=30 * 24 * 3600)
    loginInfoCountObj = None
    try:
        loginInfoCountObj = LoginInfoCount.query.filter(LoginInfoCount.login_date <= nowDay,
                                                        LoginInfoCount.login_date > thirtyAgoDate). \
            order_by(LoginInfoCount.login_date).all()
    except Exception as e:
        current_app.logger.error(e)

    activeDate = []
    activeCount = []
    for loginInfoCount in loginInfoCountObj:
        loginInfoCount = loginInfoCount.to_dict()
        activeDate.append(loginInfoCount.get("login_date"))
        activeCount.append(loginInfoCount.get("count"))
    activeDate.append(nowDateStr)
    activeCount.append(nowDayActiveUserCount)

    data = {
        "total_count": totalUserCount,
        "mon_count": nowMonthNewUserCount,
        "day_count": nowDayNewUserCount,
        "active_date": activeDate,
        "active_count": activeCount
    }
    return render_template("admin/user_count.html", data=data)


@admin_blu.route("user_list")
def user_info():
    """用户列表"""
    # 校验参数
    currentPage = request.args.get("current_page", 1)
    limit = request.args.get("limit", constants.ADMIN_USER_PAGE_MAX_COUNT)

    try:
        currentPage = int(currentPage)
        limit = int(limit)
    except Exception as e:
        current_app.logger.error(e)
        abort(404)

    usersPaginateObj = None
    try:
        usersPaginateObj = User.query.filter(User.is_admin == False).\
                                             order_by(User.create_time).paginate(currentPage, limit, False)
    except Exception as e:
        current_app.logger.error(e)

    usersPaginate = usersPaginateObj.items
    currentPage = usersPaginateObj.page
    totalPage = usersPaginateObj.pages

    users = [user.to_admin_dict() for user in usersPaginate]

    data = {
        "users": users,
        "current_page": currentPage,
        "total_page": totalPage
    }

    return render_template("admin/user_list.html", data=data)


@admin_blu.route("/news_review")
def news_review():
    """新闻审核"""
    # 校验参数
    currentPage = request.args.get("current_page", 1)
    limit = request.args.get("limit", constants.ADMIN_NEWS_PAGE_MAX_COUNT)
    keywords = request.args.get("keywords")
    try:
        currentPage = int(currentPage)
        limit = int(limit)
    except Exception as e:
        current_app.logger.error(e)
        abort(404)

    # 查数据
    newsPaginateObj = None
    filters = []
    if keywords:
        filters = [News.title.like(f"%{keywords}%")]
    try:
        newsPaginateObj = News.query.filter(*filters, News.status == 1).paginate(currentPage, limit, False)
    except Exception as e:
        current_app.logger.error(e)

    newsObj = newsPaginateObj.items
    currentPage = newsPaginateObj.page
    totalPage = newsPaginateObj.pages
    news = [news.to_review_dict() for news in newsObj]
    data = {
        "news_list": news,
        "current_page": currentPage,
        "total_page": totalPage
    }

    return render_template("admin/news_review.html", data=data)


@admin_blu.route("/news_review_detail", methods=["GET", "POST"])
def news_review_detail():
    """审核新闻详情"""
    if request.method == "GET":
        # 校验参数
        newsId = request.args.get("news_id")
        if not newsId:
            return redirect(url_for("admin.news_review"))
        newsObj = None
        try:
            newsObj = News.query.get(newsId)
        except Exception as e:
            current_app.logger.error(e)

        if not newsObj:
            current_app.logger.error(f"未查询到id为 {newsId} 的新闻信息")
            return redirect(url_for("admin.news_review"))
        news = newsObj.to_dict()
        data = {
            "news": news
        }
        return render_template("admin/news_review_detail.html", data=data)
    else:
        # 校验参数
        dataDict = request.json
        newsId = dataDict.get("news_id")
        action = dataDict.get("action")
        reason = dataDict.get("reason")

        if not all([newsId, action]):
            return info_jsonfy(RET.PARAMERR, "参数错误")
        if action not in ["accept", "reject"]:
            return info_jsonfy(RET.PARAMERR, "参数错误")
        if action == "reject" and (not reason):
            return info_jsonfy(RET.PARAMERR, "参数错误")

        try:
            news = News.query.get(newsId)
        except Exception as e:
            current_app.logger.error(e)
            return info_jsonfy(RET.DBERR, "数据库错误")
        if action == "accept":
            news.status = 0
        else:
            news.status = -1
            news.reason = reason
        return info_jsonfy(RET.OK, "success")


@admin_blu.route("/news_edit")
def news_edit():
    """新闻版式编辑"""
    # 校验参数
    currentPage = request.args.get("current_page", 1)
    limit = request.args.get("limit", constants.ADMIN_NEWS_PAGE_MAX_COUNT)
    keywords = request.args.get("keywords")
    try:
        currentPage = int(currentPage)
        limit = int(limit)
    except Exception as e:
        current_app.logger.error(e)
        abort(404)

    filters = [News.status != 0]
    if keywords:
        filters.append(News.title.like(f"{keywords}"))

    paginate = None
    try:
        paginate = News.query.filter(*filters).order_by(News.create_time).paginate(currentPage, limit, False)
    except Exception as e:
        current_app.logger.error(e)

    newsObj = paginate.items
    currentPage = paginate.page
    totalPage = paginate.pages

    news = [news.to_basic_dict() for news in newsObj]

    data = {
        "current_page": currentPage,
        "total_page": totalPage,
        "news_list": news
    }

    return render_template("admin/news_edit.html", data=data)


@admin_blu.route("/news_edit_detail", methods=["GET", "POST"])
def news_edit_detail():
    """新闻版式详情编辑"""
    if request.method == "GET":
        # 校验参数
        newsId = request.args.get("news_id")
        if not newsId:
            return redirect(url_for("admin.news_edit"))
        newsObj = None
        try:
            newsObj = News.query.get(newsId)
        except Exception as e:
            current_app.logger.error(e)

        if not newsObj:
            current_app.logger.error(f"未查询到id为 {newsId} 的新闻信息")
            return redirect(url_for("admin.news_edit"))
        news = newsObj.to_dict()

        categoryObj = []
        try:
            categoryObj = Category.query.all()
        except Exception as e:
            current_app.logger.error(e)

        categories = []
        for category in categoryObj:
            categoryDict = category.to_dict()
            categoryDict["isSelected"] = False
            if category.id == newsObj.category_id:
                categoryDict["isSelected"] = True
            if category.name != "最新":
                categories.append(category)

        data = {
            "news": news,
            "categories": categories
        }
        return render_template("admin/news_edit_detail.html", data=data)
    else:
        # 校验参数
        dataForm = request.form
        newsId = dataForm.get("news_id")
        title = dataForm.get("title")
        digest = dataForm.get("digest")
        content = dataForm.get("content")
        indexImage = request.files.get("index_image")
        categoryId = dataForm.get("category_id")

        if not all([newsId, title, digest, content, categoryId]):
            return info_jsonfy(RET.PARAMERR, "参数错误")
        try:
            news = News.query.get(newsId)
        except Exception as e:
            current_app.logger.error(e)
            return info_jsonfy(RET.DBERR, "数据库查询错误")
        if not news:
            return info_jsonfy(RET.NODATA, "新闻数据不存在")

        try:
            category = Category.query.get(categoryId)
        except Exception as e:
            current_app.logger.error(e)
            return info_jsonfy(RET.DBERR, "数据库查询错误")
        if not category:
            return info_jsonfy(RET.NODATA, "新闻类型不存在")

        if indexImage:
            try:
                indexImage = indexImage.read()
            except Exception as e:
                current_app.logger.error(e)
                return info_jsonfy(RET.PARAMERR, "参数有误")
            try:
                key = storage(indexImage)
            except Exception as e:
                current_app.logger.error(e)
                return info_jsonfy(RET.THIRDERR, "图片上传错误")
            news.index_image_url = key

        news.title = title
        news.digest = digest
        news.content = content
        news.category_id = categoryId
        news.update_time = datetime.now()
        news.status = 0
        news.reason = None
        return info_jsonfy(RET.OK, "success")


@admin_blu.route("/news_category")
@get_category_info
def news_category():
    """新闻分类编辑"""
    categories = g.categoryList
    for category in categories:
        if category.get("name") == "最新":
            categories.remove(category)
            break
    data = {
        "categories": categories
    }
    return render_template("admin/news_category.html", data=data)


@admin_blu.route("/add_category", methods=["POST"])
def add_category():
    """修改分类"""
    dataDict = request.json
    categoryId = dataDict.get("id")
    categoryName = dataDict.get("name")
    if not categoryName:
        return info_jsonfy(RET.PARAMERR, "分类名称不能为空")
    if not categoryId:
        category = Category()
        category.id = random_uuid()
        category.name = categoryName
        db.session.add(category)
    else:
        try:
            category = Category.query.get(categoryId)
        except Exception as e:
            current_app.logger.error(e)
            return info_jsonfy(RET.DBERR, "数据库错误")
        category.name = categoryName
    return info_jsonfy(RET.OK, "success")
